package book

import (
	"NovelBook/dao"
	"NovelBook/models/db_models"
	"NovelBook/models/res"
	"math"
	"strconv"
	"time"

	"gorm.io/gorm"
)

func GetBorrowedInfoByBorrowerID(borrowerID uint) ([]db_models.BorrowInfo, error) {
	var borrowTables []db_models.BorrowTable
	borrowInfos := make([]db_models.BorrowInfo, 0)

	if err := dao.GetDb().Preload("Borrower").Preload("Book").Where("borrower_id = ?", borrowerID).Find(&borrowTables).Error; err != nil {
		return nil, err
	}

	// 计算借书截止日期和是否超时
	nowTs := time.Now().UnixNano() / int64(time.Millisecond)
	for _, bt := range borrowTables {
		deadline := bt.StartTime + db_models.MaxTime
		isOverdue := false
		fine := 0

		if err := dao.GetDb().Preload("Book").Where("id = ?", bt.BooksNumberID).Find(&bt.BooksNumber).Error; err != nil {
			return nil, err
		}

		switch bt.ReturnTime {
		// 用户未还书
		case 0:
			isOverdue = nowTs > deadline
		// 用户已还书
		default:
			isOverdue = bt.ReturnTime > deadline
			switch isOverdue {
			case true:
				fine = int(math.Ceil(float64(bt.ReturnTime-bt.StartTime) / (1000 * 60 * 60 * 24)))
			}
		}

		borrowInfos = append(borrowInfos, db_models.BorrowInfo{BorrowTable: bt, Deadline: deadline, IsOverdue: isOverdue, Fine: fine})
	}
	return borrowInfos, nil
}

func GetBorrowedInfoByBookID(BookID int) ([]res.BorrowedInfo, error) {
	Info := make([]res.BorrowedInfo, 0)
	var BorrowTable []db_models.BorrowTable

	switch err := dao.GetDb().Preload("Book").Preload("Borrower").Where("book_id = ? and is_returned = false", BookID).Find(&BorrowTable).Error; err {
	case nil:

	case gorm.ErrRecordNotFound:
		return Info, err
	default:
		return nil, err
	}

	for _, borrow := range BorrowTable {
		var m res.BorrowedInfo
		m.Account = borrow.Borrower.Info.Account
		m.Avatar = borrow.Borrower.Info.Avatar
		m.Email = borrow.Borrower.Info.Email
		m.Username = borrow.Borrower.Info.Username
		m.BookID = uint(BookID)
		m.ISBN = borrow.Book.ISBN
		m.BookNo = borrow.BooksNumberID
		m.BookUniqueID = strconv.Itoa(BookID) + "-" + strconv.Itoa(int(borrow.BooksNumberID))

		Info = append(Info, m)
	}
	return Info, nil
}
